From 1106b119946a09f6b715a8cab7d7444fca760414 Mon Sep 17 00:00:00 2001 From: Wei Wang Date: Thu, 12 Jan 2012 13:53:20 +0100 Subject: [PATCH] amd iommu: Enable guest level translation Similar to nested paging for SVM, IOMMUv2 supports two level translations for DMA. This patch enables this feature. Signed-off-by: Wei Wang Committed-by: Jan Beulich --- xen/drivers/passthrough/amd/iommu_init.c | 25 +++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/xen/drivers/passthrough/amd/iommu_init.c b/xen/drivers/passthrough/amd/iommu_init.c index 647d3828c7..6185ca61bf 100644 --- a/xen/drivers/passthrough/amd/iommu_init.c +++ b/xen/drivers/passthrough/amd/iommu_init.c @@ -217,12 +217,29 @@ static void set_iommu_translation_control(struct amd_iommu *iommu, entry = readl(iommu->mmio_base + IOMMU_CONTROL_MMIO_OFFSET); enable ? - iommu_set_bit(&entry, IOMMU_CONTROL_TRANSLATION_ENABLE_SHIFT): + iommu_set_bit(&entry, IOMMU_CONTROL_TRANSLATION_ENABLE_SHIFT) : iommu_clear_bit(&entry, IOMMU_CONTROL_TRANSLATION_ENABLE_SHIFT); writel(entry, iommu->mmio_base+IOMMU_CONTROL_MMIO_OFFSET); } +static void set_iommu_guest_translation_control(struct amd_iommu *iommu, + int enable) +{ + u32 entry; + + entry = readl(iommu->mmio_base + IOMMU_CONTROL_MMIO_OFFSET); + + enable ? + iommu_set_bit(&entry, IOMMU_CONTROL_GT_ENABLE_SHIFT) : + iommu_clear_bit(&entry, IOMMU_CONTROL_GT_ENABLE_SHIFT); + + writel(entry, iommu->mmio_base+IOMMU_CONTROL_MMIO_OFFSET); + + if ( enable ) + AMD_IOMMU_DEBUG("Guest Translation Enabled.\n"); +} + static void set_iommu_command_buffer_control(struct amd_iommu *iommu, int enable) { @@ -658,6 +675,9 @@ static void enable_iommu(struct amd_iommu *iommu) if ( iommu_has_feature(iommu, IOMMU_EXT_FEATURE_PPRSUP_SHIFT) ) set_iommu_ppr_log_control(iommu, IOMMU_CONTROL_ENABLED); + if ( iommu_has_feature(iommu, IOMMU_EXT_FEATURE_GTSUP_SHIFT) ) + set_iommu_guest_translation_control(iommu, IOMMU_CONTROL_ENABLED); + set_iommu_translation_control(iommu, IOMMU_CONTROL_ENABLED); if ( iommu_has_feature(iommu, IOMMU_EXT_FEATURE_IASUP_SHIFT) ) @@ -998,6 +1018,9 @@ static void disable_iommu(struct amd_iommu *iommu) if ( iommu_has_feature(iommu, IOMMU_EXT_FEATURE_PPRSUP_SHIFT) ) set_iommu_ppr_log_control(iommu, IOMMU_CONTROL_DISABLED); + if ( iommu_has_feature(iommu, IOMMU_EXT_FEATURE_GTSUP_SHIFT) ) + set_iommu_guest_translation_control(iommu, IOMMU_CONTROL_DISABLED); + set_iommu_translation_control(iommu, IOMMU_CONTROL_DISABLED); iommu->enabled = 0; -- 2.30.2